#pragma once;

#include "common.h"
#include "contact.h"


namespace TorPhysix{
	class ContactResolver
    {
		friend class World;
    protected:
		// Number of iterations to use when resolving velocity
        unsigned velocityIterations;

		// Number of iterations to use when resolving position
        unsigned positionIterations;

		// Velocities smaller than this value are assumed to be zero, this is because too small values lead to instability. 0.01 is a good start. Fudge factor
        real velocityEpsilon;

		// Objects that are interpenetrating with a depth lower than this value are not considered interpenetrating. 0.01 is a good start. Fudge factor
        real positionEpsilon;

    public:
        unsigned velocityIterationsUsed;
        unsigned positionIterationsUsed;

    private:
        // Keeps track of whether the internal settings are valid.
        bool validSettings;

    public:

		ContactResolver();

        /**
         * Returns true if the resolver has valid settings and is ready to go.
         */
        bool isValid()
        {
            return (velocityIterations > 0) &&
                   (positionIterations > 0) &&
                   (positionEpsilon >= 0.0f) &&
                   (velocityEpsilon >= 0.0f);
        }

        void setIterations(unsigned velocityIterations, unsigned positionIterations);

        // Sets the tolerance value for both velocity and position.
        void setEpsilon(real velocityEpsilon,  real positionEpsilon);

        /**
         * Resolves a set of contacts for both penetration and velocity.
         *
         * Contacts that cannot interact with
         * each other should be passed to separate calls to resolveContacts,
         * as the resolution algorithm takes much longer for lots of
         * contacts than it does for the same number of contacts in small
         * sets.
         *
         * @param contactArray Pointer to an array of contact objects.
         *
         * @param numContacts The number of contacts in the array to resolve.
         *
         * @param numIterations The number of iterations through the
         * resolution algorithm. This should be at least the number of
         * contacts (otherwise some constraints will not be resolved -
         * although sometimes this is not noticeable). If the iterations are
         * not needed they will not be used, so adding more iterations may
         * not make any difference. In some cases you would need millions
         * of iterations. Think about the number of iterations as a bound:
         * if you specify a large number, sometimes the algorithm WILL use
         * it, and you may drop lots of frames.
         *
         * @param duration The duration of the previous integration step.
         * This is used to compensate for forces applied.
         */
		void resolveContacts(TorPhysix::Contact *contactArray, unsigned numContacts, real duration);

    protected:
        /**
         * Sets up contacts ready for processing. This makes sure their
         * internal data is configured correctly and the correct set of bodies
         * is made alive.
         */
        void prepareContacts(Contact *contactArray, unsigned numContacts, real duration);

        /**
         * Resolves the velocity issues with the given array of constraints,
         * using the given number of iterations.
         */
        void adjustVelocities(Contact *contactArray, unsigned numContacts, real duration);

        /**
         * Resolves the positional issues with the given array of constraints,
         * using the given number of iterations.
         */
        void adjustPositions(Contact *contacts, unsigned numContacts);
    };
}